package Olivia.olivia3d.shader
{
	public class FragmentShader
	{
		protected static var fsAgal:String="";
		
		public function FragmentShader()
		{
			
		}
		
		public static function getFsAgal(shadow:Boolean=true,diff:Boolean=true,spec:Boolean=true):String
		{
			fsAgal = "";
			
			//shadow ft2
			if(shadow){
				addShadow();
			}
			
			//normal v1---> ft3;
			if(diff || spec){
				fsAgal += "nrm ft3.xyz, v1\n" + 
					"mov ft3.w, fc5.w\n";
			}
			
			//diff ft4;
			if(diff){
				diffuseLight();
			}
			
			//spec ft5;
			if(spec){
				specularLight();
				fsAgal += "add ft4, ft4, ft5\n";
			}
			
			//matrial v0--->ft6
			fsAgal += "tex ft6, v0, fs1 <2d,repeat,linear>\n";
			
			if(shadow){
				fsAgal += "mul ft6, ft2.wwww, ft6\n";
			}
						
			if(diff){
				fsAgal += 
					"add ft4, ft4, fc0\n"+		//+ ambient
					"mul ft6, ft4, ft6\n"+		//x material
//					"mul ft3, ft3, fc4\n"+		//x 光颜色强度
					"add ft6, ft6, fc3\n";		//+ emissive
					//光的衰减
//					"mul ft4, ft4, ft6.w\n"+
			}
			
			//oc
			fsAgal +=
				"mul ft6, ft6, fc7.x\n"+
				"mul ft6, ft6, fc9\n"+			//pick model
				"mov oc, ft6";
			
			return fsAgal;
		}
		
		
		protected static function addShadow():void
		{
			fsAgal += 
				"mov ft1, v1\n" +
				"tex ft0, v1, fs0 <2d, nearest, clamp>\n" +
				"dp4 ft0.z, ft0, fc8\n" +
				"sub ft0.z, ft0.z, fc7.w\n" +
				"slt ft1.z, v1.z, ft0.z\n"+
//				"mov ft2.w, ft1.z\n"+
				"add ft1.x, v1.x, fc7.z\n" +
				"tex ft0, ft1, fs0 <2d, nearest, clamp>\n" +
				"dp4 ft0.z, ft0, fc8\n" +
				"sub ft0.z, ft0.z, fc7.w\n" +
				"slt ft1.w, v1.z, ft0.z\n" +
				"mul ft0.x, v1.x, fc7.y\n" +
				"frc ft0.x, ft0.x\n" +
				"sub ft1.w, ft1.w, ft1.z\n" +
				"mul ft1.w, ft1.w, ft0.x\n" +
				"add ft2.w, ft1.z, ft1.w\n" +
				"mov ft1.x, v1.x\n" +
				"add ft1.y, v1.y, fc7.z\n" +
				"tex ft0, ft1, fs0 <2d, nearest, clamp>\n" +
				"dp4 ft0.z, ft0, fc8\n" +
				"sub ft0.z, ft0.z, fc7.w\n" +
				"slt ft1.z, v1.z, ft0.z\n" +
				"add ft1.x, v1.x, fc7.z\n" +
				"tex ft0, ft1, fs0 <2d, nearest, clamp>\n" +
				"dp4 ft0.z, ft0, fc8\n" +
				"sub ft0.z, ft0.z, fc7.w\n" +
				"slt ft1.w, v1.z, ft0.z\n" +
				"mul ft0.x, v1.x, fc7.y\n" +
				"frc ft0.x, ft0.x\n" +
				"sub ft1.w, ft1.w, ft1.z\n" +
				"mul ft1.w, ft1.w, ft0.x\n" +
				"add ft1.w, ft1.z, ft1.w\n" +
				"mul ft0.x, v1.y, fc7.y\n" +
				"frc ft0.x, ft0.x\n" +
				"sub ft1.w, ft1.w, ft2.w\n" +
				"mul ft1.w, ft1.w, ft0.x\n" +
				"add ft2.w, ft2.w, ft1.w\n" +
				"add ft2.w, ft2.w, fc7.y\n" +
				"sat ft2.w, ft2.w\n";
////				"mul ft3.xyz, ft3.xyz, ft2.w\n"+
////				"add ft2.w, ft2.w, fc4.x\n"+
////				"sat ft5.z, ft5.z\n"+
//				"tex ft3, v0, fs1 <2d,linear,nomip>\n" +
//				"mul oc ft3, ft2.wwww";
////				"mov oc ft2";;
		}
		
		protected static function diffuseLight():void
		{			
			fsAgal +=
				"dp3 ft4, ft3, fc5\n"+		//n.l
				"neg ft4, ft4\n"+		//-n.l
				"sat ft4, ft4\n"+		//n.l:0
				"mul ft4, ft4, fc1\n";	//漫反射 x系数
		}
		
		protected static function specularLight():void
		{
			fsAgal +=
				//镜面反射
				//镜像向量
				"dp3 ft5, ft1, fc5\n"+			//n.l
				"add ft5, ft5, ft5\n"+			//2(n.l)
				"mul ft5, ft5, ft1\n"+			//2(n.l)n
				"sub ft5, ft5, fc5\n"+			//2(n.l)n-l			
				//计算 观察者 的 方向
				"nrm ft6.xyz, v2\n"+			//nrm(vertexviewMat)
				"mov ft6.w, fc5.w\n"+
				"sub ft6, fc4, ft6\n"+			//eyePosition - vertexviewMat
				"nrm ft6.xyz, ft6.xyz\n"+		//normal--->观察者的方向			
				//计算出vr的夹角
				"dp3 ft5, ft5, ft6\n"+			//(2(n.l)n-l).v = cosθ			
				"sat ft5, ft5\n"+				//cosθ:0
				"mul ft5, ft5, fc2\n";			//镜面反射x系数
		}
		
//		protected static function lightAttenuation():String
//		{
//			//计算光源 到顶点的距离
//				"sub ft6, v3, fc2\n"+			//顶点减去光源		fc2光源位置
//				"mul ft6, ft6, ft6\n"+			//平方			
//				"add ft6.w, ft6.x, ft6.y\n"+	//w=x+y
//				"add ft6.w, ft6.w, ft6.z\n"+	//w=x+y+z			
//				"sqt ft6.w, ft6.w\n"+			//w=sqt(w)
//				
//				//衰减系数
//				"sub ft6.w, fc5.y, ft6.w\n"+	//w=dmax-d			
//				"div ft6.w, ft6.w, fc5.w\n"+	//w=(dmax-d)/(dmax-dmin)
//				
//				//fc4.z = 0;
//				"max ft6.w, ft6.w, fc5.z\n"+	//消除 小于0
//				//fc4.x = 1;
//				"min ft6.w, ft6.w, fc5.x\n"+	//消除大于1
//			return null;
//		}
		
		public static function depthFsAgal():String
		{
			return "div ft2, v0, v0.w\n" +
				"mul ft0, fc0, ft2.z\n" +
				"frc ft0, ft0\n" +
				"mul ft1, ft0.yzww, fc1\n" +
				"sub oc, ft0, ft1\n";
		}
		
		public static function pickFsAgal():String
		{
			return "mov oc, fc0";		
		}
	}
}